#pragma once
#include "gp_XYZ.h"

class gp_Dir;
class gp_XYZ;
class gp_Pnt;
class gp_Ax1;
class gp_Ax2;
class gp_Trsf;

//!  Defines a non-persistent vector in 3D space. <br>
class gp_Vec  {

public:

  

  //! Creates a zero vector. <br>
      gp_Vec();
  //! Creates a unitary vector from a direction V. <br>
      gp_Vec(const gp_Dir& V);
  //! Creates a vector with a triplet of coordinates. <br>
      gp_Vec(const gp_XYZ& Coord);
  //! Creates a point with its three cartesian coordinates. <br>
      gp_Vec(const double Xv,const double Yv,const double Zv);
  
//!  Creates a vector from two points. The length of the vector <br>
//!  is the distance between P1 and P2 <br>
      gp_Vec(const gp_Pnt& P1,const gp_Pnt& P2);
  //! Changes the coordinate of range Index <br>
//!  Index = 1 => X is modified <br>
//!  Index = 2 => Y is modified <br>
//!  Index = 3 => Z is modified <br>//! Raised if Index != {1, 2, 3}. <br>
        void SetCoord(const int Index,const double Xi) ;
  //! For this vector, assigns <br>
//! -   the values Xv, Yv and Zv to its three coordinates. <br>
        void SetCoord(const double Xv,const double Yv,const double Zv) ;
  //! Assigns the given value to the X coordinate of this vector. <br>
        void SetX(const double X) ;
  //! Assigns the given value to the X coordinate of this vector. <br>
        void SetY(const double Y) ;
  //! Assigns the given value to the X coordinate of this vector. <br>
        void SetZ(const double Z) ;
  //! Assigns the three coordinates of Coord to this vector. <br>
        void SetXYZ(const gp_XYZ& Coord) ;
  
//!  Returns the coordinate of range Index : <br>
//!  Index = 1 => X is returned <br>
//!  Index = 2 => Y is returned <br>
//!  Index = 3 => Z is returned <br>//! Raised if Index != {1, 2, 3}. <br>
        double Coord(const int Index) const;
  //! For this vector returns its three coordinates Xv, Yv, and Zv <br>
        void Coord(double& Xv,double& Yv,double& Zv) const;
  //! For this vector, returns its X coordinate. <br>
        double X() const;
  //! For this vector, returns its Y coordinate. <br>
        double Y() const;
  //! For this vector, returns its Z  coordinate. <br>
        double Z() const;
  //!    For this vector, returns <br>
//! -   its three coordinates as a number triple <br>
       const gp_XYZ& XYZ() const;
  
//!  Returns True if the two vectors have the same magnitude value <br>
//!  and the same direction. The precision values are LinearTolerance <br>
//!  for the magnitude and AngularTolerance for the direction. <br>
       bool IsEqual(const gp_Vec& Other,const double LinearTolerance,const double AngularTolerance) const;
  
//!  Returns True if abs(<me>.Angle(Other) - PI/2.) <= AngularTolerance <br>
//!   Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or <br>
//!  Other.Magnitude() <= Resolution from gp <br>
        bool IsNormal(const gp_Vec& Other,const double AngularTolerance) const;
  
//!  Returns True if PI - <me>.Angle(Other) <= AngularTolerance <br>
//!  Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or <br>
//!  Other.Magnitude() <= Resolution from gp <br>
        bool IsOpposite(const gp_Vec& Other,const double AngularTolerance) const;
  
//!  Returns True if Angle(<me>, Other) <= AngularTolerance or <br>
//!  PI - Angle(<me>, Other) <= AngularTolerance <br>
//!  This definition means that two parallel vectors cannot define <br>
//!  a plane but two vectors with opposite directions are considered <br>
//!  as parallel. Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution or <br>
//!  Other.Magnitude() <= Resolution from gp <br>
        bool IsParallel(const gp_Vec& Other,const double AngularTolerance) const;
  
//!  Computes the angular value between <me> and <Other> <br>
//!  Returns the angle value between 0 and PI in radian. <br>
//!    Raises VectorWithNullMagnitude if <me>.Magnitude() <= Resolution from gp or <br>
//!  Other.Magnitude() <= Resolution because the angular value is <br>
//!  indefinite if one of the vectors has a null magnitude. <br>
        double Angle(const gp_Vec& Other) const;
  //! Computes the angle, in radians, between this vector and <br>
//! vector Other. The result is a value between -Pi and Pi. <br>
//! For this, VRef defines the positive sense of rotation: the <br>
//! angular value is positive, if the cross product this ^ Other <br>
//! has the same orientation as VRef relative to the plane <br>
//! defined by the vectors this and Other. Otherwise, the <br>
//! angular value is negative. <br>
//! Exceptions <br>
//! gp_VectorWithNullMagnitude if the magnitude of this <br>
//! vector, the vector Other, or the vector VRef is less than or <br>
//! equal to gp::Resolution(). <br>
//! Standard_DomainError if this vector, the vector Other, <br>
//! and the vector VRef are coplanar, unless this vector and <br>
//! the vector Other are parallel. <br>
        double AngleWithRef(const gp_Vec& Other,const gp_Vec& VRef) const;
  //! Computes the magnitude of this vector. <br>
        double Magnitude() const;
  //! Computes the square magnitude of this vector. <br>//! Adds two vectors <br>
        double SquareMagnitude() const;
  
        void Add(const gp_Vec& Other) ;
      void operator +=(const gp_Vec& Other) 
{
  Add(Other);
}
  //! Adds two vectors <br>//! Subtracts two vectors <br>
        gp_Vec Added(const gp_Vec& Other) const;
      gp_Vec operator +(const gp_Vec& Other) const
{
  return Added(Other);
}
  
        void Subtract(const gp_Vec& Right) ;
      void operator -=(const gp_Vec& Right) 
{
  Subtract(Right);
}
  //! Subtracts two vectors <br>//! Multiplies a vector by a scalar <br>
        gp_Vec Subtracted(const gp_Vec& Right) const;
      gp_Vec operator -(const gp_Vec& Right) const
{
  return Subtracted(Right);
}
  
        void Multiply(const double Scalar) ;
      void operator *=(const double Scalar) 
{
  Multiply(Scalar);
}
  //! Multiplies a vector by a scalar <br>//! Divides a vector by a scalar <br>
        gp_Vec Multiplied(const double Scalar) const;
      gp_Vec operator *(const double Scalar) const
{
  return Multiplied(Scalar);
}
  
        void Divide(const double Scalar) ;
      void operator /=(const double Scalar) 
{
  Divide(Scalar);
}
  //! Divides a vector by a scalar <br>//! computes the cross product between two vectors <br>
        gp_Vec Divided(const double Scalar) const;
      gp_Vec operator /(const double Scalar) const
{
  return Divided(Scalar);
}
  
        void Cross(const gp_Vec& Right) ;
      void operator ^=(const gp_Vec& Right) 
{
  Cross(Right);
}
  //! computes the cross product between two vectors <br>
        gp_Vec Crossed(const gp_Vec& Right) const;
      gp_Vec operator ^(const gp_Vec& Right) const
{
  return Crossed(Right);
}
  
//!  Computes the magnitude of the cross <br>
//!  product between <me> and Right. <br>
//!  Returns || <me> ^ Right || <br>
        double CrossMagnitude(const gp_Vec& Right) const;
  
//!  Computes the square magnitude of <br>
//!  the cross product between <me> and Right. <br>
//!  Returns || <me> ^ Right ||**2 <br>//! Computes the triple vector product. <br>
//!  <me> ^ (V1 ^ V2) <br>
        double CrossSquareMagnitude(const gp_Vec& Right) const;
  
        void CrossCross(const gp_Vec& V1,const gp_Vec& V2) ;
  //! Computes the triple vector product. <br>
//!  <me> ^ (V1 ^ V2) <br>
        gp_Vec CrossCrossed(const gp_Vec& V1,const gp_Vec& V2) const;
  //! computes the scalar product <br>
        double Dot(const gp_Vec& Other) const;
      double operator *(const gp_Vec& Other) const
{
  return Dot(Other);
}
  //! Computes the triple scalar product <me> * (V1 ^ V2). <br>//! normalizes a vector <br>
//!  Raises an exception if the magnitude of the vector is <br>
//!  lower or equal to Resolution from gp. <br>
        double DotCross(const gp_Vec& V1,const gp_Vec& V2) const;
  
        void Normalize() ;
  //! normalizes a vector <br>
//!  Raises an exception if the magnitude of the vector is <br>
//!  lower or equal to Resolution from gp. <br>//! Reverses the direction of a vector <br>
        gp_Vec Normalized() const;
  
        void Reverse() ;
  //! Reverses the direction of a vector <br>
        gp_Vec Reversed() const;
      gp_Vec operator -() const
{
  return Reversed();
}
  
//!  <me> is setted to the following linear form : <br>
//!  A1 * V1 + A2 * V2 + A3 * V3 + V4 <br>
        void SetLinearForm(const double A1,const gp_Vec& V1,const double A2,const gp_Vec& V2,const double A3,const gp_Vec& V3,const gp_Vec& V4) ;
  
//!  <me> is setted to the following linear form : <br>
//!  A1 * V1 + A2 * V2 + A3 * V3 <br>
        void SetLinearForm(const double A1,const gp_Vec& V1,const double A2,const gp_Vec& V2,const double A3,const gp_Vec& V3) ;
  
//!  <me> is setted to the following linear form : <br>
//!  A1 * V1 + A2 * V2 + V3 <br>
        void SetLinearForm(const double A1,const gp_Vec& V1,const double A2,const gp_Vec& V2,const gp_Vec& V3) ;
  
//!  <me> is setted to the following linear form : <br>
//!  A1 * V1 + A2 * V2 <br>
        void SetLinearForm(const double A1,const gp_Vec& V1,const double A2,const gp_Vec& V2) ;
  
//!  <me> is setted to the following linear form : A1 * V1 + V2 <br>
        void SetLinearForm(const double A1,const gp_Vec& V1,const gp_Vec& V2) ;
  
//!  <me> is setted to the following linear form : V1 + V2 <br>
        void SetLinearForm(const gp_Vec& V1,const gp_Vec& V2) ;
  
       void Mirror(const gp_Vec& V) ;
  
//!  Performs the symmetrical transformation of a vector <br>
//!  with respect to the vector V which is the center of <br>
//!  the  symmetry. <br>
       gp_Vec Mirrored(const gp_Vec& V) const;
  
       void Mirror(const gp_Ax1& A1) ;
  
//!  Performs the symmetrical transformation of a vector <br>
//!  with respect to an axis placement which is the axis <br>
//!  of the symmetry. <br>
       gp_Vec Mirrored(const gp_Ax1& A1) const;
  
       void Mirror(const gp_Ax2& A2) ;
  
//!  Performs the symmetrical transformation of a vector <br>
//!  with respect to a plane. The axis placement A2 locates <br>
//!  the plane of the symmetry : (Location, XDirection, YDirection). <br>
       gp_Vec Mirrored(const gp_Ax2& A2) const;
  
        void Rotate(const gp_Ax1& A1,const double Ang) ;
  
//!  Rotates a vector. A1 is the axis of the rotation. <br>
//!  Ang is the angular value of the rotation in radians. <br>
        gp_Vec Rotated(const gp_Ax1& A1,const double Ang) const;
  
        void Scale(const double S) ;
  //! Scales a vector. S is the scaling value. <br>//! Transforms a vector with the transformation T. <br>
        gp_Vec Scaled(const double S) const;
  
       void Transform(const gp_Trsf& T) ;
  //! Transforms a vector with the transformation T. <br>
        gp_Vec Transformed(const gp_Trsf& T) const;
    const gp_XYZ& _CSFDB_Getgp_Veccoord() const { return coord; }



protected:




private: 


gp_XYZ coord;


};






// other  functions and methods (like "C++: function call" methods)



